package com.example.sourcecodelearning.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.manticoresearch.client.api.IndexApi;
import com.manticoresearch.client.api.SearchApi;
import com.manticoresearch.client.api.UtilsApi;
import com.manticoresearch.client.model.*;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Component
public class ManticoreSearchUtils {

    @Resource
    private IndexApi indexApi;

    @Resource
    private SearchApi searchApi;

    @Resource
    private UtilsApi utilsApi;

    @SneakyThrows
    public List<Object> createTable(String sql) {
        return utilsApi.sql(sql, Boolean.TRUE);
    }

    @SneakyThrows
    public SuccessResponse insert(String index, Map<String, Object> doc) {
        InsertDocumentRequest newdoc = new InsertDocumentRequest();
        newdoc.index(index).setDoc(doc);
        return indexApi.insert(newdoc);
    }

    @SneakyThrows
    public <T> SuccessResponse insert(String index, T entity) {
        InsertDocumentRequest newdoc = new InsertDocumentRequest();
        Map<String, Object> doc = BeanUtil.beanToMap(entity, true, false);
        newdoc.index(index).setDoc(doc);
        return indexApi.insert(newdoc);
    }

    @Transactional(rollbackFor = Exception.class)
    @SneakyThrows
    public <T> SuccessResponse batchInsert(String index, List<T> entityList) {
        for (T entity : entityList) {
            InsertDocumentRequest newdoc = new InsertDocumentRequest();
            // 使用下划线、不忽略空值
            Map<String, Object> doc = BeanUtil.beanToMap(entity, true, false);
            newdoc.index(index).setDoc(doc);
            indexApi.insert(newdoc);
        }
        return null;
    }

    @SneakyThrows
    public List<Object> select(String sql) {
        return utilsApi.sql(sql, false);
    }

    @SneakyThrows
    public SearchResponse select(String index, String[] highlightFieldNames) {
        Map<String, Object> query = new HashMap<>();
        query.put("query_string", "@title remove hair");
        SearchRequest searchRequest = new SearchRequest()
                .index(index);
        searchRequest.setQuery(query);
        if (ObjectUtil.isNotEmpty(highlightFieldNames)) {
            List<HighlightField> highlightFieldList = Arrays.stream(highlightFieldNames)
                    .map(name -> new HighlightField().name(name))
                    .collect(Collectors.toList());
            Highlight highlight = new Highlight();
            highlight.setFields(highlightFieldList);
            searchRequest.setHighlight(highlight);
        }
        return searchApi.search(searchRequest);
    }

    @SneakyThrows
    public UpdateResponse update(String index, Long id, Map<String, Object> condition) {
        UpdateDocumentRequest updateRequest = new UpdateDocumentRequest();
        updateRequest.index(index).id(id).setDoc(condition);
        return indexApi.update(updateRequest);
    }

    @SneakyThrows
    public DeleteResponse delete(String index, Map<String, Object> condition) {
        DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest();
        deleteRequest.index(index).setQuery(condition);
        return indexApi.delete(deleteRequest);
    }

}
